if (!dojo._hasResource["dojoide.core._autocomplete"]) {
    dojo._hasResource["dojoide.core._autocomplete"] = true;
    dojo.provide("dojoide.core._autocomplete");

    
    //Params object is used to specify filter criteria for listObjectMembers function
    dojoide.core._autocomplete.Params = function(excludePrivates, excludeAttributes, excludeFunctions, excludeValues, filterStr, sortList){
        this.excludePrivates = excludePrivates ? excludePrivates : false;
        this.excludeAttributes = excludeAttributes ? excludeAttributes : false;
        this.excludeFunctions = excludeFunctions ? excludeFunctions : false;
        this.excludeValues = excludeValues ? excludeValues : false;
        this.filterStr = filterStr;
        this.sortList = sortList ? sortList : false;
    };
    
    //ObjectMember object is used to hold the name, type, and value of the object members
    dojoide.core._autocomplete.ObjectMember = function(objName, objType, objValue){
        this.objName = objName;
        this.objType = objType;
        this.objValue = objValue;
        this.toString = function(){
	        return '' 
	        	+ (this.objName?this.objName:'') 
	        	+ (this.objType?' : ' + this.objType:'') 
	        	+ (this.objType == 'function' || this.objValue == null?'':' = ' + this.objValue);
        };
    };
    
    dojoide.core._autocomplete.listObjectMembers = function(obj, params){
        /**
         * This function lists an object's (obj) members and values according 
         * to the specified values defined in the params parameter.
         */
        var objMemArr = [];
        var memCounter = -1;
        //list object members
        for (var objMem in obj) {
            try {
                if (params) {
                    if (params.excludePrivates && objMem.startsWith('_')) {
                        continue;
                    }
                    if (params.excludeAttributes && !dojo.isFunction(obj[objMem])) {
                        continue;
                    }
                    if (params.excludeFunctions && dojo.isFunction(obj[objMem])) {
                        continue;
                    }
                    if (params.filterStr && !objMem.startsWith(params.filterStr)) {
                        continue;
                    }
                    if (params.excludeValues) {
                        objMemArr.push(new dojoide.core._autocomplete.ObjectMember(objMem, typeof(obj[objMem])));
                    } else {
                        objMemArr.push(new dojoide.core._autocomplete.ObjectMember(objMem, typeof(obj[objMem]), obj[objMem]));
                    }
                }
            } catch (err) {
                console.warn('Error identifying object attributes: '+ objMem);
                console.warn(err);
            }
        }
        if (params && params.sortList) {
            objMemArr.sort();
        }
        return objMemArr;
    };
    
    dojoide.core.listObjectAttributes = function(obj, filterStr){
        var params = new dojoide.core._autocomplete.Params();
        params.excludePrivates = true;
        params.excludeAttributes = false;
        params.excludeFunctions = true;
        params.excludeValues = true;
        params.filterStr = filterStr;
        params.sortList = true;
        return dojoide.core._autocomplete.listObjectMembers(obj, params);
    };
    
    dojoide.core.listObjectFunctions = function(obj, filterStr){
        var params = new dojoide.core._autocomplete.Params();
        params.excludePrivates = true;
        params.excludeAttributes = true;
        params.excludeFunctions = false;
        params.excludeValues = true;
        params.filterStr = filterStr;
        params.sortList = true;
        return dojoide.core._autocomplete.listObjectMembers(obj, params);
    };
    
    dojoide.core.listObjectEvents = function(obj){
        var params = new dojoide.core._autocomplete.Params();
        params.excludePrivates = true;
        params.excludeAttributes = true;
        params.excludeFunctions = false;
        params.excludeValues = true;
        params.filterStr = 'on';
        params.sortList = true;
        return dojoide.core._autocomplete.listObjectMembers(obj, params);
    };
    
    dojoide.core.listObjectMembers = function(obj, filterStr){
        var params = new dojoide.core._autocomplete.Params();
        params.excludePrivates = true;
        params.excludeAttributes = false;
        params.excludeFunctions = false;
        params.excludeValues = true;
        params.filterStr = filterStr;
        params.sortList = true;
        return dojoide.core._autocomplete.listObjectMembers(obj, params);
    };
    
    dojoide.core.listObjectAttributesAndValues = function(obj, filterStr){
        var params = new dojoide.core._autocomplete.Params();
        params.excludePrivates = true;
        params.excludeAttributes = false;
        params.excludeFunctions = true;
        params.excludeValues = false;
        params.filterStr = filterStr;
        params.sortList = true;
        return dojoide.core._autocomplete.listObjectMembers(obj, params);
    };
    
    dojoide.core.listAllObjectMembers = function(obj, filterStr){
        var params = new dojoide.core._autocomplete.Params();
        params.excludePrivates = false;
        params.excludeAttributes = false;
        params.excludeFunctions = false;
        params.excludeValues = true;
        params.filterStr = filterStr;
        params.sortList = true;
        return dojoide.core._autocomplete.listObjectMembers(obj, params);
    };
    
    dojoide.core.listAllObjectAttributesAndValues = function(obj, filterStr){
        var params = new dojoide.core._autocomplete.Params();
        params.excludePrivates = false;
        params.excludeAttributes = false;
        params.excludeFunctions = true;
        params.excludeValues = false;
        params.filterStr = filterStr;
        params.sortList = true;
        return dojoide.core._autocomplete.listObjectMembers(obj, params);
    };
    
    dojoide.core.listAllObjectMembersAndValues = function(obj, filterStr){
        var params = new dojoide.core._autocomplete.Params();
        params.excludePrivates = false;
        params.excludeAttributes = false;
        params.excludeFunctions = false;
        params.excludeValues = false;
        params.filterStr = filterStr;
        params.sortList = true;
        return dojoide.core._autocomplete.listObjectMembers(obj, params);
    };
}
